#!/bin/bash

IMAGE_DIR=$1
IMAGE_FILE=$1/UEFI-BIOS.bin
BIOS_MTD_DEVICE=""

SPI_DEV='2803d000.spi'
SPI_PATH='/sys/bus/platform/drivers/phytium_spi'

# GPIO5_2
SPI_GPIO=418

Current_version=""
Update_version=""

get_bios_version()
{
    FILE=$IMAGE_DIR
    ID=${FILE##*/}
    OBJ='xyz.openbmc_project.Software.BMC.Updater'
    OBJ_PATH="/xyz/openbmc_project/software/$ID"
    INTERFACE='xyz.openbmc_project.Software.Version'
    PROPERTY='Version'
    CMD="busctl get-property  $OBJ $OBJ_PATH $INTERFACE $PROPERTY"
    str=$($CMD)
    str=${str#*\"}
    Update_version=${str%%\"*}

    OBJ_PATH="/xyz/openbmc_project/software/bios_active"
    CMD="busctl get-property  $OBJ $OBJ_PATH $INTERFACE $PROPERTY"
    str=$($CMD)
    str=${str#*\"}
    Current_version=${str%%\"*}

    return 0
}

generate_redfish_log()
{
    if [ ! -d "/var/log" ]; then
        mkdir -p /var/log
    fi

    OPENBMC_TAG="OpenBMC.0.1.$1"
    PARA=""
    shift
    while [ $# -ne 0 ]; do
        PARA=$PARA",$1"
        shift
    done
    logger -p local7.info "${OPENBMC_TAG}${PARA}"
}

check_cmd_state()
{
    if [ $? -eq 0 ]; then
        echo "$1 Successfully..."
        return 0
    else
        echo "$1 Failed..."
        generate_redfish_log "FirmwareUpdateFailed" "$Current_version" "$Update_version" "$1 Failed..."
        sleep 3 ##Response time reserved for front-end detection
                if [[ $2 != "NOT_EXIT" ]]; then
                    exit 1 ##exit script
                else
            return 1
        fi
    fi
}

check_mtd_device()
{
    all_mtd_device=`ls /sys/class/mtd/mtd*/name`
    for mtd in $all_mtd_device ; do
        d=`cat $mtd`
        if [[ $d == $1 ]]; then
            tmp=${mtd%/*}
            BIOS_MTD_DEVICE=/dev/${tmp##*/}
            return 0
        fi
    done
    echo "Not find $1 mtd device"
    return 1
}

setup_spi_drive()
{
    if [[ $1 == "bind" ]]; then
        if [[ -d ${SPI_PATH}/$SPI_DEV ]]; then
            echo  "${SPI_DEV}" > ${SPI_PATH}/unbind
        fi
        echo  "${SPI_DEV}" > ${SPI_PATH}/bind
        check_mtd_device "pnor"
            return $?
    elif [[ $1 == "unbind" ]] && [[ -d ${SPI_PATH}/$SPI_DEV ]]; then
        echo  "${SPI_DEV}" > ${SPI_PATH}/unbind
    fi
    sleep 1 #Response time reserved for CPLD detection
    return 0;
}

#Set GPIO to make CPLD enable or disable spi channel  of BIOS
setup_bios_update()
{
    echo "Setup BMC Update BIOS: Flash to $1"
    if [[ "$1" == "bmc" ]] && [[ "$data" == "1" ]]; then
        gpioutil set CPU_SPI_SELECT 1
    elif [[ "$1" == "cpu" ]] && [[ "$data" == "0" ]]; then
        gpioutil set CPU_SPI_SELECT 0
    fi
    sleep 1 #Response time reserved for CPLD detection
    return 0
}

##Set bios update dbus progress interface
## $1=Progress
set_dbus_progress_info()
{
    FILE=$IMAGE_DIR
    ID=${FILE##*/}
    OBJ='xyz.openbmc_project.Software.BMC.Updater'
    OBJ_PATH="/xyz/openbmc_project/software/$ID"
    INTERFACE='xyz.openbmc_project.Software.ActivationProgress'
    PROPERTY='Progress'

    busctl set-property  $OBJ $OBJ_PATH $INTERFACE $PROPERTY y $1
    check_cmd_state "Set FW:$ID progress=$1% progress to dbus interface"
#   echo "Set FW:$ID progress=$1%"
    return 0
}
##Flash the new firmware into the BIOS
start_flash_BIOS()
{
    echo "Flashing bios image to $BIOS_MTD_DEVICE..."
    if [ ! -e $BIOS_MTD_DEVICE ]; then
        generate_redfish_log "FirmwareUpdateFailed" "$Current_version" "$Update_version" "flashcp updated Failed : BIOS mtd device $BIOS_MTD_DEVICE does not exist"
        return 1
    fi
    #
    ##Added progress monitoring function
    #
    echo "wait" > /tmp/bios_flash_progress
    sh /usr/local/progress_monitoring.sh $IMAGE_DIR $1 $2&
    #sleep 2
    flashcp -v $IMAGE_FILE $BIOS_MTD_DEVICE > /tmp/bios_flash_progress
    if [ $? -eq 0 ]; then
        echo "bios flashcp updated successfully..."
    else
        echo "bios flashcp updated Failed..."
        echo "Unbind spi driver"
        setup_spi_drive "unbind"
        generate_redfish_log "FirmwareUpdateFailed" "$Current_version" "$Update_version" "flashcp updated Failed..."
        sleep 3 ##Response time reserved for front-end detection
        return 1
    fi
    echo "end" > /tmp/bios_flash_progress
    wait #Wait for the subscript progress_monitoring.sh to exit
    echo "wait finish!!!! end shell"

    return 0
}

#############################################################
#
#MIAN
#
#############################################################
echo "Bios upgrade started at $(date)"

get_bios_version

#Check the file to be burned
set_dbus_progress_info 21
if [ ! -e "$IMAGE_FILE" ]; then
    echo "Bios image $IMAGE_FILE doesn't exist"
    generate_redfish_log "FirmwareUpdateFailed" "$Current_version" "$Update_version" "Uploading the wrong firmware,BIOS image $IMAGE_FILE doesn't exist"
    sleep 3 ##Response time reserved for front-end detection
    exit 1
fi

#Flip GPIO to access SPI flash used by host.
setup_bios_update "bmc" #Enable Update,BIOS to BMC
set_dbus_progress_info 22

#Bind spi driver to access flash
echo "Start bind bmc spi controller driver"
setup_spi_drive "bind"
check_cmd_state "Search SPI CPU BIOS Flash " $2
set_dbus_progress_info 25

#Flashcp image to device.
echo "Single BIOS Mode:Bios image is $IMAGE_FILE"
start_flash_BIOS 30 100

echo "Start Unbind bmc spi controller driver"
setup_spi_drive "unbind"

#Flip GPIO back for host to access SPI flash
setup_bios_update "cpu" #Disable Update,BIOS to CPU

generate_redfish_log "FirmwareUpdateCompleted" "$Current_version" "$Update_version"
echo "Bios eeprom service update finish"
